﻿// ===============================================================================
// XCI.NET 西安交通信息WinForm开发框架 2018 版权所有
// ===============================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace XCI.Helper
{
    /// <summary>
    /// 全局热键操作类
    /// </summary>
    /// <remarks>
    /// <para>1.注册全局热键 </para>
    /// <para>2.复合热键的支持，如Ctrl+E,Ctrl+L或Ctrl+E,L</para>
    /// </remarks>
    /// <example>
    /// <code>
    /// using XCI.Helper;
    /// 
    /// Win32Helper.AllocConsole(); 
    /// //定义热键状态消息输出
    /// HotkeyHelper.StatusOut = ShowMessage;
    /// //注册热键
    /// HotKeyHelper.Register(new HotKey("test1", ControlKeys.Ctrl, Keys.R, Execute));
    /// HotKeyHelper.Register(new HotKey("test2", ControlKeys.Shift, Keys.R, Execute));
    /// HotKeyHelper.Register(new HotKey("test3", ControlKeys.Ctrl | ControlKeys.Shift, Keys.R, Execute));
    /// HotKeyHelper.Register(new HotKey("test4", ControlKeys.Ctrl | ControlKeys.Alt | ControlKeys.Shift, Keys.R, Execute));
    /// HotKeyHelper.Register(new HotKey("test5", ControlKeys.Ctrl, Keys.F, new CombinationKeys(ControlKeys.None, Keys.B), Execute));
    /// HotKeyHelper.Register(new HotKey("test6", ControlKeys.Ctrl, Keys.D, new CombinationKeys(ControlKeys.Ctrl, Keys.B), Execute));
    /// HotKeyHelper.Register(new HotKey("test7", ControlKeys.Ctrl, Keys.W, new CombinationKeys(ControlKeys.Shift, Keys.D), Execute));
    /// HotKeyHelper.Register(new HotKey("test8", ControlKeys.Ctrl | ControlKeys.Shift, Keys.D, new CombinationKeys(ControlKeys.Ctrl, Keys.B), Execute));
    /// HotKeyHelper.Register(new HotKey("test9", ControlKeys.Ctrl | ControlKeys.Shift, Keys.E, new CombinationKeys(ControlKeys.Ctrl | ControlKeys.Shift, Keys.V), Execute));
    /// HotKeyHelper.Register(new HotKey("test10", ControlKeys.Ctrl | ControlKeys.Shift | ControlKeys.Alt, Keys.U, new CombinationKeys(ControlKeys.Ctrl | ControlKeys.Shift | ControlKeys.Alt, Keys.Y), Execute));
    /// 
    /// //读取热键列表
    /// ShowHotKeyList();
    /// Console.WriteLine();
    /// 
    /// /*****************************************************************************************************/
    /// 
    /// private static void ShowHotKeyList()
    /// {
    ///     Console.WriteLine();
    ///     Console.ForegroundColor = ConsoleColor.Gray;
    ///     //读取热键列表
    ///     var list = HotkeyHelper.GetHotKeyList();
    ///     foreach (HotKey key in list)
    ///     {
    ///         Console.WriteLine(string.Format("名称:{0},键:{1},状态:{2}", key.Name, key, key.IsRegisted));
    ///     }
    /// }
    /// 
    /// private static void ShowMessage(string msg)
    /// {
    ///     Console.ForegroundColor = ConsoleColor.Green;
    ///     Console.WriteLine("状态消息:"+msg);
    /// }
    /// 
    /// private static void Execute(HotKey hotkey)
    /// {
    ///     Console.ForegroundColor = ConsoleColor.Red;
    ///     Console.WriteLine(string.Format("用户处理->您按下了:{0}", hotkey));
    /// } 
    /// </code>
    /// <img src="images/HotkeyHelper.jpg" />
    /// </example>
    public static class HotKeyHelper
    {
        /// <summary>
        /// 热键监听器
        /// </summary>
        private static readonly HotKeyListener _hotKeyListener = new HotKeyListener();

        /// <summary>
        /// 热键状态消息输出
        /// </summary>
        public static Action<string> StatusOut { get; set; }

        /// <summary>
        /// 静态构造
        /// </summary>
        static HotKeyHelper()
        {
            _hotKeyListener.StateChanged += _hotKeyListener_StateChanged;
        }

        static void _hotKeyListener_StateChanged(HotKeyListener arg1, string msg)
        {
            if (StatusOut != null)
            {
                StatusOut(msg);
            }
        }

        /// <summary>
        /// 注册热键
        /// </summary>
        /// <param name="hotKey">热键对象</param>
        /// <returns>成功返回true</returns>
        public static bool Register(HotKey hotKey)
        {
            return _hotKeyListener.Register(hotKey);
        }

        /// <summary>
        /// 注销热键
        /// </summary>
        /// <param name="hotKey">热键对象</param>
        /// <returns>成功返回true</returns>
        public static bool UnRegister(HotKey hotKey)
        {
            return _hotKeyListener.UnRegister(hotKey);
        }

        /// <summary>
        /// 注销热键
        /// </summary>
        /// <param name="name">热键名称</param>
        /// <returns>成功返回true</returns>
        public static bool UnRegister(string name)
        {
            return _hotKeyListener.UnRegister(GetHotKey(name));
        }

        /// <summary>
        /// 注销全部热键
        /// </summary>
        public static void UnRegisterAll()
        {
            _hotKeyListener.UnRegisterAll();
        }

        /// <summary>
        /// 暂停全部热键
        /// </summary>
        public static void SuspendAll()
        {
            _hotKeyListener.SuspendAll();
        }

        /// <summary>
        /// 恢复全部热键
        /// </summary>
        public static void RestoreAll()
        {
            _hotKeyListener.RestoreAll();
        }

        /// <summary>
        /// 获取热键
        /// </summary>
        /// <param name="name">热键名称</param>
        /// <returns>返回热键对象</returns>
        public static HotKey GetHotKey(string name)
        {
            return _hotKeyListener.HotKeys.FirstOrDefault(p => p.Name.Equals(name));
        }

        /// <summary>
        /// 获取热键列表
        /// </summary>
        /// <returns>返回热键列表</returns>
        public static HotKey[] GetHotKeyList()
        {
            return _hotKeyListener.HotKeys.ToArray();
        }
    }

    /// <summary>
    /// 系统热键
    /// </summary>
    public class HotKey
    {
        private readonly string _name;
        private readonly ControlKeys _controlkey;
        private readonly Keys _key;
        private readonly CombinationKeys _combinationkey;

        /// <summary>
        /// 热键标识
        /// </summary>
        internal int Id { get; set; }

        /// <summary>
        /// 名称
        /// </summary>
        public string Name
        {
            get { return _name; }
        }

        /// <summary>
        /// 控制键
        /// </summary>
        public ControlKeys ControlKey
        {
            get { return _controlkey; }
        }

        /// <summary>
        /// 键代码
        /// </summary>
        public Keys Key
        {
            get { return _key; }
        }

        /// <summary>
        /// 注册状态
        /// </summary>
        public bool IsRegisted { get; set; }

        /// <summary>
        /// 组合键
        /// </summary>
        public CombinationKeys CombinationKey
        {
            get { return _combinationkey; }
        }

        /// <summary>
        /// 热键执行函数
        /// </summary>
        public Action<HotKey> Execute { get; set; }

        /// <summary>
        /// 构造热键
        /// </summary>
        /// <param name="name">热键名称</param>
        /// <param name="controlKey">控制键</param>
        /// <param name="key">键代码</param>
        /// <param name="execute">热键执行函数</param>
        public HotKey(string name, ControlKeys controlKey, Keys key, Action<HotKey> execute)
            : this(name, controlKey, key, null, execute) { }

        /// <summary>
        /// 构造热键
        /// </summary>
        /// <param name="name">热键名称</param>
        /// <param name="controlKey">控制键</param>
        /// <param name="key">键代码</param>
        /// <param name="combinationKey">组合键</param>
        /// <param name="execute">热键执行函数</param>
        public HotKey(string name, ControlKeys controlKey, Keys key, CombinationKeys combinationKey, Action<HotKey> execute)
        {
            if (name == null) throw new ArgumentNullException("name");
            //if (key == Keys.None) return;

            _name = name;
            _key = key;
            _controlkey = controlKey;
            _combinationkey = combinationKey;
            Execute = execute;
        }

        /// <summary>
        /// 热键描述
        /// </summary>
        /// <returns>返回热键描述</returns>
        public override string ToString()
        {
            string mainKey = GetMainKeyName();
            string combinationkey = GetCombinationKeyName();
            if (!string.IsNullOrEmpty(combinationkey))
            {
                return mainKey + ("," + combinationkey);
            }
            return mainKey;
        }

        /// <summary>
        /// 主键描述
        /// </summary>
        /// <returns>返回主键描述</returns>
        public string GetMainKeyName()
        {
            return string.Concat(ControlKey.ToString().Replace(", ", "+"), "+", Key);
        }

        /// <summary>
        /// 组合键描述
        /// </summary>
        /// <returns>返回组合键描述</returns>
        public string GetCombinationKeyName()
        {
            if (CombinationKey == null) return string.Empty;
            return CombinationKey.ToString();
        }
    }

    /// <summary>
    /// 热键监听
    /// </summary>
    public class HotKeyListener : IDisposable
    {
        /// <summary>
        /// 注册热键信息
        /// </summary>
        struct RegisteredHotKey
        {
            public ControlKeys ControlKey;
            public Keys Key;
            public int Id;
        }

        /// <summary>
        /// 是否正在等待按下复合键中的子键
        /// </summary>
        private bool waitingCombinationKey;

        private readonly Form _listeningForm = new Form { Visible = false };

        private readonly ICollection<CombinationKeys> _combinationHotKey = new List<CombinationKeys>();

        /// <summary>
        /// 缓存的热键
        /// </summary>
        private readonly List<RegisteredHotKey> _cacheHotKeys = new List<RegisteredHotKey>();

        /// <summary>
        /// 热键字典
        /// </summary>
        internal Dictionary<int, HotKey> _hotKeysDic = new Dictionary<int, HotKey>();

        /// <summary>
        /// 消息过滤
        /// </summary>
        private readonly HotKeyMessageFilter _messageFilter;

        /// <summary>
        /// 下一个热键ID
        /// </summary>
        private int nextId = 100;

        /// <summary>
        /// 最后一次按下的热键
        /// </summary>
        private HotKey _lastPressedHotKey;

        ///// <summary>
        ///// 最后一次按下热键的时间
        ///// </summary>
        //private DateTime _lastPressedTime = DateTime.MinValue;

        /// <summary>
        /// 构造热键监听
        /// </summary>
        public HotKeyListener()
        {
            _messageFilter = new HotKeyMessageFilter(this);
            Application.AddMessageFilter(_messageFilter);
        }

        #region 属性

        /// <summary>
        /// 热键集合
        /// </summary>
        public IEnumerable<HotKey> HotKeys
        {
            get { return _hotKeysDic.Values; }
        }

        /// <summary>
        /// 组合键集合
        /// </summary>
        private ICollection<CombinationKeys> CombinationHotKey
        {
            get { return _combinationHotKey; }
        }

        #endregion

        #region 事件

        ///// <summary>
        ///// 热键按下事件
        ///// </summary>
        //public event HotKeyPressedHandler HotKeyPressed;

        ///// <summary>
        ///// 热键
        ///// </summary>
        //public event HotKeyPressedHandler HotKeyDoublePressed;

        /// <summary>
        /// 状态信息变化后
        /// </summary>
        public event Action<HotKeyListener, string> StateChanged;

        #endregion

        #region 方法

        /// <summary>
        /// 暂停全部热键
        /// </summary>
        public void SuspendAll()
        {
            _cacheHotKeys.Clear();
            foreach (var hotKey in HotKeys)
            {
                if (hotKey.Id > 0)
                {
                    _cacheHotKeys.Add(new RegisteredHotKey { Id = hotKey.Id, Key = hotKey.Key, ControlKey = hotKey.ControlKey });
                }
            }
            foreach (var hotKey in CombinationHotKey)
            {
                if (hotKey.Id > 0)
                {
                    _cacheHotKeys.Add(new RegisteredHotKey { Id = hotKey.Id, Key = hotKey.Key, ControlKey = hotKey.ControlKey });
                }
            }
            _cacheHotKeys.ForEach(hotkey =>
            {
                NativeMethods.UnregisterHotKey(_listeningForm.Handle, hotkey.Id);
                if (_hotKeysDic.ContainsKey(hotkey.Id))
                {
                    _hotKeysDic[hotkey.Id].IsRegisted = false;
                }
            });
            InvokeStateInfoChanged("暂停全部热键");
        }

        /// <summary>
        /// 恢复全部热键
        /// </summary>
        public void RestoreAll()
        {
            _cacheHotKeys.ForEach(
                hotkey =>
                {
                    NativeMethods.RegisterHotKey(_listeningForm.Handle, hotkey.Id, (uint)hotkey.ControlKey, hotkey.Key);
                    if (_hotKeysDic.ContainsKey(hotkey.Id))
                    {
                        _hotKeysDic[hotkey.Id].IsRegisted = true;
                    }
                });
            _cacheHotKeys.Clear();
            InvokeStateInfoChanged("恢复全部热键");
        }

        /// <summary>
        /// 注册热键
        /// </summary>
        /// <param name="hotKey">热键对象</param>
        /// <exception cref="InvalidOperationException">已经存在相同的热键</exception>
        /// <returns>注册成功返回true</returns>
        public bool Register(HotKey hotKey)
        {
            //检测是否注册
            foreach (HotKey key in _hotKeysDic.Values)
            {
                if (key.Name == hotKey.Name)
                {
                    throw new InvalidOperationException(string.Format("此热键名称已经被注册:{0}", hotKey));
                }

                if (key.Key == hotKey.Key && key.ControlKey == hotKey.ControlKey)
                {
                    if (key.CombinationKey == null || hotKey.CombinationKey == null)
                    {
                        throw new InvalidOperationException(string.Format("此热键已经被注册:{0}", hotKey));
                    }
                    if (key.Key == hotKey.CombinationKey.Key && key.CombinationKey.ControlKey == hotKey.CombinationKey.ControlKey)
                    {
                        throw new InvalidOperationException(string.Format("此热键已经被注册:{0}", hotKey));
                    }
                }
            }

            //开始注册热键
            hotKey.Id = nextId;
            _hotKeysDic.Add(nextId, hotKey);
            var res = NativeMethods.RegisterHotKey(_listeningForm.Handle, nextId, (uint)(hotKey.ControlKey), hotKey.Key);
            //更新热键的注册状态
            hotKey.IsRegisted = res;
            nextId++;
            InvokeStateInfoChanged("注册热键:" + hotKey);
            return res;
        }

        /// <summary>
        /// 注销热键
        /// </summary>
        /// <param name="hotKey">热键对象</param>
        /// <returns>成功返回true</returns>
        public bool UnRegister(HotKey hotKey)
        {
            if (hotKey == null) return false;

            if (_hotKeysDic.ContainsKey(hotKey.Id))
            {
                var res = NativeMethods.UnregisterHotKey(_listeningForm.Handle, hotKey.Id);
                InvokeStateInfoChanged("注销热键:" + hotKey);
                _hotKeysDic.Remove(hotKey.Id);
                return res;
            }
            return false;
        }

        /// <summary>
        /// 获取复合键
        /// </summary>
        /// <returns>返回复合键列表</returns>
        List<CombinationKeys> GetCombinationHotKeys(HotKey mainHotKey)
        {
            var q = from _hotKey in HotKeys
                    where _hotKey.ControlKey == mainHotKey.ControlKey && _hotKey.Key == mainHotKey.Key &&
                        _hotKey.CombinationKey != null
                    select _hotKey.CombinationKey;
            return q.ToList();
        }

        /// <summary>
        /// 注册复合快捷键的子键
        /// </summary>
        /// <param name="combinationHotKeys"></param>
        void RegisterCombinationKey(List<CombinationKeys> combinationHotKeys)
        {
            _combinationHotKey.Clear();
            combinationHotKeys.ForEach(p =>
            {
                _combinationHotKey.Add(p);
                var find = HotKeys.AsQueryable().FirstOrDefault(
                    hotkey => hotkey.Key == p.Key && hotkey.ControlKey == p.ControlKey);
                if (find == null)
                {
                    p.IsRegisted = true;
                    p.Id = nextId;
                    NativeMethods.RegisterHotKey(_listeningForm.Handle, nextId, (uint)(p.ControlKey), p.Key);
                    nextId++;
                }
            });
        }

        /// <summary>
        /// 注销本程序注册的所有组合键的子键
        /// </summary>
        void UnRegisterCombinationKeys()
        {
            CombinationHotKey.ToList().ForEach(
                hotkey =>
                {
                    if (hotkey.IsRegisted)
                    {
                        NativeMethods.UnregisterHotKey(_listeningForm.Handle, hotkey.Id);
                    }
                });
            CombinationHotKey.Clear();
        }

        /// <summary>
        /// 注销全部热键
        /// </summary>
        public void UnRegisterAll()
        {
            int[] idList = new int[_hotKeysDic.Count];
            _hotKeysDic.Keys.CopyTo(idList, 0);
            foreach (int id in idList)
            {
                NativeMethods.UnregisterHotKey(_listeningForm.Handle, id);
                _hotKeysDic.Remove(id);
            }
            UnRegisterCombinationKeys();
            InvokeStateInfoChanged("注销全部热键");
        }

        void InvokeSystemHotKeyPressed(HotKey hotKey, bool regCombinationKeys)
        {
            List<CombinationKeys> combinationKeys = null;
            if (regCombinationKeys)
            {
                combinationKeys = GetCombinationHotKeys(hotKey);
            }
            if (combinationKeys == null || combinationKeys.Count == 0)
            {
                InvokeStateInfoChanged("调用热键:" + hotKey);
                //HotKeyPressedEventArgs e = new HotKeyPressedEventArgs(hotKey);
                //2011.04.15 lugreen 去掉对"双击"快捷键的支持
                //if (_lastPressedHotKey == hotKey)
                //{
                //    TimeSpan diff = DateTime.Now.Subtract(_lastPressedTime);
                //    if (diff.TotalMilliseconds <= SystemInformation.DoubleClickTime)
                //    {
                //        // Double click
                //        _lastPressedTime = DateTime.MinValue;

                //        OnSystemHotKeyDoublePressed(e);
                //        return;
                //    }
                //}                
                //_lastPressedTime = DateTime.Now;
                // Single click
                _lastPressedHotKey = null;
                OnHotKeyPressed(hotKey);
            }
            else
            {
                _lastPressedHotKey = hotKey;
                //_lastPressedTime = DateTime.Now;
                waitingCombinationKey = true;
                RegisterCombinationKey(combinationKeys);//注册组合键
                InvokeStateInfoChanged(string.Format("{0}已按下,正在等待按下第二个键...", _lastPressedHotKey.GetMainKeyName()));
                //注册子键                                
            }
        }

        /// <summary>
        /// 调用组合快捷键
        /// </summary>
        /// <param name="combinationHotKey"></param>
        internal void InvokeCombinationHotKeyPressed(CombinationKeys combinationHotKey)
        {
            var q = from key in HotKeys
                    where key.ControlKey == _lastPressedHotKey.ControlKey && key.Key == _lastPressedHotKey.Key
                      && key.CombinationKey != null && key.CombinationKey.Key == combinationHotKey.Key &&
                      key.CombinationKey.ControlKey == combinationHotKey.ControlKey
                    select key;
            OnHotKeyPressed(q.FirstOrDefault());
        }

        /// <summary>
        /// 热键按下事件处理函数
        /// </summary>
        /// <param name="hotkey">热键对象</param>
        private void OnHotKeyPressed(HotKey hotkey)
        {
            if (hotkey != null && hotkey.Execute != null)
            {
                hotkey.Execute(hotkey);
            }
            //if (HotKeyPressed != null)
            //{
            //    HotKeyPressedHandler invoker = HotKeyPressed;
            //    invoker(this, e);
            //}
        }

        //protected virtual void OnSystemHotKeyDoublePressed(HotKeyPressedEventArgs e)
        //{
        //    if (SystemHotKeyDoublePressed != null)
        //    {
        //        HotKeyPressedHandler invoker = SystemHotKeyDoublePressed;
        //        invoker(this, e);
        //    }
        //}

        internal void ProcessHotkey(Message m)
        {
            if (m.Msg == NativeConstants.WM_HOTKEY)
            {
                ControlKeys modifiers = GetModifiers(m.LParam);
                Keys key = GetKey(m.LParam);

                int sid = m.WParam.ToInt32();

                if (!waitingCombinationKey)
                {
                    //Debug.WriteLine("nowaiting");
                    if (this._hotKeysDic.ContainsKey(sid))
                    {
                        //Debug.WriteLine("containskey");
                        HotKey hotKey = this._hotKeysDic[sid];
                        this.InvokeSystemHotKeyPressed(hotKey, true);
                    }
                    else
                    {
                        //Debug.WriteLine("nocontainskey");
                        InvokeStateInfoChanged("无效按键");
                    }
                }
                else
                {
                    //Debug.WriteLine("waitingKey");
                    waitingCombinationKey = false;

                    //查找复合键                    
                    var finded = CombinationHotKey.FirstOrDefault(combinationKey => combinationKey.Key == key
                        && combinationKey.ControlKey == modifiers);

                    if (finded != null)
                    {
                        var findedHotKey = FindHotKey(_lastPressedHotKey, finded);
                        if (findedHotKey != null)
                        {
                            this.InvokeSystemHotKeyPressed(findedHotKey, false);
                        }
                        //else
                        //{
                        //    //Debug.WriteLine("not found childkey");
                        //}
                    }
                    else
                    {
                        var tmpHotkey = new CombinationKeys(modifiers, key);
                        InvokeStateInfoChanged(string.Format("热键({0})未注册",
                            _lastPressedHotKey.GetMainKeyName() + "," + tmpHotkey));
                    }
                    UnRegisterCombinationKeys();
                }
            }
            else
            {
                if (m.Msg == NativeConstants.WM_KEYDOWN)
                {
                    Keys pressedKey = (Keys)m.WParam;
                    //Debug.WriteLine("按下:" + pressedKey + "-" + (int)pressedKey);
                    if (waitingCombinationKey)
                    {
                        //如果按下了访问键，则查找是否注册了访问键相关的热键
                        if (pressedKey != Keys.ControlKey && pressedKey != Keys.ShiftKey && pressedKey != Keys.Alt)
                        {
                            String msg = String.Format("组合键({0},{1})不是命令", _lastPressedHotKey.GetMainKeyName(), pressedKey);
                            InvokeStateInfoChanged(msg);
                            waitingCombinationKey = false;
                            UnRegisterCombinationKeys();
                        }
                    }

                }

            }
        }

        /// <summary>
        /// 查找具有指定主键的和子键的热键
        /// </summary>
        /// <param name="mainKey">主键过滤</param>
        /// <param name="combinationHotKey">子键过滤</param>
        /// <returns></returns>
        private HotKey FindHotKey(HotKey mainKey, CombinationKeys combinationHotKey)
        {
            var q = from key in HotKeys
                    where key.CombinationKey != null
                          && key.Key == mainKey.Key
                          && key.ControlKey == mainKey.ControlKey
                          && key.CombinationKey.Key == combinationHotKey.Key
                          && key.CombinationKey.ControlKey == combinationHotKey.ControlKey
                    select key;
            var r = q.FirstOrDefault();
            return r;
        }

        Keys GetKey(IntPtr lparam)
        {
            return (Keys)(((int)lparam >> 16) & 0xFFFF);
        }

        ControlKeys GetModifiers(IntPtr lparam)
        {
            ControlKeys modifier = (ControlKeys)((int)lparam & 0xFFFF);
            return modifier;
        }

        void InvokeStateInfoChanged(string stateMsg)
        {
            Action<HotKeyListener, string> handler = StateChanged;
            if (handler != null) handler(this, stateMsg);
        }

        #endregion

        #region IDisposable Members

        /// <summary>
        /// 注销全部热键并释放资源
        /// </summary>
        public void Dispose()
        {
            UnRegisterAll();
            _listeningForm.Dispose();
        }

        #endregion
    }

    /// <summary>
    /// 组合键
    /// </summary>
    public class CombinationKeys
    {
        private readonly ControlKeys _controlkey;
        private readonly Keys _key;
        private int _id = -1;

        /// <summary>
        /// 控制键
        /// </summary>
        public ControlKeys ControlKey
        {
            get { return _controlkey; }
        }

        /// <summary>
        /// 键代码
        /// </summary>
        public Keys Key
        {
            get { return _key; }
        }

        /// <summary>
        /// 是否注册
        /// </summary>
        public bool IsRegisted { get; set; }

        /// <summary>
        /// 组合键标识
        /// </summary>
        public int Id
        {
            get { return _id; }
            set { _id = value; }
        }

        /// <summary>
        /// 构造组合键
        /// </summary>
        /// <param name="controlKey">控制键</param>
        /// <param name="key">键代码</param>
        public CombinationKeys(ControlKeys controlKey, Keys key)
        {
            _controlkey = controlKey;
            _key = key;
        }

        /// <summary>
        /// 组合键描述
        /// </summary>
        /// <returns>返回组合键描述</returns>
        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();

            if (_controlkey != ControlKeys.None)
            {
                sb.Append(_controlkey.ToString().Replace(", ", "+"));
                sb.Append("+");
            }

            if (_key != Keys.None)
            {
                sb.Append(_key);
            }
            return sb.ToString();
        }
    }

    ///// <summary>
    ///// 热键处理事件
    ///// </summary>
    ///// <param name="sender">发送者</param>
    ///// <param name="e">事件参数</param>
    //public delegate void HotKeyPressedHandler(object sender, HotKeyPressedEventArgs e);

    ///// <summary>
    ///// 热键处理事件参数
    ///// </summary>
    //public class HotKeyPressedEventArgs : EventArgs
    //{
    //    private readonly HotKey _hotKey;

    //    /// <summary>
    //    /// 按下的热键对象
    //    /// </summary>
    //    public HotKey PressedHotKey
    //    {
    //        get { return _hotKey; }
    //    }

    //    /// <summary>
    //    /// 按下的热键名称
    //    /// </summary>
    //    public string HotKeyName
    //    {
    //        get { return _hotKey.Name; }
    //    }

    //    /// <summary>
    //    /// 构造热键处理事件参数
    //    /// </summary>
    //    /// <param name="hotKey">按下的热键对象</param>
    //    public HotKeyPressedEventArgs(HotKey hotKey)
    //    {
    //        _hotKey = hotKey;
    //    }
    //}

    /// <summary>
    /// 热键消息过滤
    /// </summary>
    internal class HotKeyMessageFilter : IMessageFilter
    {
        private readonly HotKeyListener _listener;

        /// <summary>
        /// 构造热键消息过滤
        /// </summary>
        /// <param name="listener">热键监听</param>
        public HotKeyMessageFilter(HotKeyListener listener)
        {
            if (listener == null) throw new ArgumentNullException("listener");
            _listener = listener;
        }

        #region IMessageFilter Members

        public bool PreFilterMessage(ref Message m)
        {
            _listener.ProcessHotkey(m);
            //switch (m.Msg)
            //{
            //    case HotKeyApi.WM_HOTKEY:
            //        // Get the system hot key message.
            //        _listner.ProcessHotkey(m);
            //        break;
            //}
            return false;
        }

        #endregion
    }

    /// <summary>
    /// 控制键
    /// </summary>
    [Flags]
    public enum ControlKeys
    {
        /// <summary>
        /// 不使用控制键
        /// </summary>
        None = 0,

        /// <summary>
        /// 按下Alt键
        /// </summary>
        Alt = 1,

        /// <summary>
        /// 按下Ctrl键
        /// </summary>
        Ctrl = 2,

        /// <summary>
        /// 按下Shift键
        /// </summary>
        Shift = 4,

        /// <summary>
        /// 按下Windows键
        /// </summary>
        Windows = 8
    }
}